#ifndef SMART_ARRAY_IMPL_H
#define SMART_ARRAY_IMPL_H

#include <assert.h>

template <class T, unsigned int prealloc>
class SmartArrayImpl
{
	unsigned int reserved_;
	unsigned int used_;
	T *array_;
	bool arrayOwner_;
public:
	SmartArrayImpl() : reserved_(prealloc), used_(0),
		array_(new T[reserved_]), arrayOwner_(true)
	{
		if (array_ == 0)
			reserved_ = 0;
	}
	SmartArrayImpl(SmartArrayImpl &smartArrayImpl)
	{
		assert(smartArrayImpl.arrayOwner_); // use an exception instead later?
		reserved_ = smartArrayImpl.reserved_;
		used_ = smartArrayImpl.used_;
		array_ = smartArrayImpl.array_;
		smartArrayImpl.arrayOwner_ = false;
		arrayOwner_ = true;
	}
	virtual ~SmartArrayImpl()
	{
		if (true == arrayOwner_ && 0 != array_)
			delete [] array_;
	}
	void operator=(SmartArrayImpl &smartArrayImpl)
	{
		assert(smartArrayImpl.arrayOwner_); // use an exception instead later?
		reserved_ = smartArrayImpl.reserved_;
		used_ = smartArrayImpl.used_;
		if (true == arrayOwner_ && 0 != array_)
			delete [] array_;
		array_ = smartArrayImpl.array_;
		smartArrayImpl.arrayOwner_ = false;
		arrayOwner_ = true;
	}
	bool add(const T &t)
	{
		if (arrayOwner_ == false)
			return false;
		if (used_ >= reserved_) {
			if (reserved_ >= 256)
				return false;
			else {
				T *array = new T[2 * reserved_];
				if (array == 0) // if no exception thrown
					return false;   // then just return false
				for (unsigned int i = 0; i < reserved_; i++)
					array[i] = array_[i];
				reserved_ *= 2;
				if (array_ != 0)
					delete [] array_;
				array_ = array;
			}
		}
		array_[used_] = t;
		used_++;
		return true;
	}
	T *begin() { return array_; }
	T *end() { return array_ + used_; }
};

#endif